//-----------------------------------------------------------------------------
// Fnnn_TargetBL_DevSpecific.c
//-----------------------------------------------------------------------------
// Copyright (C) 2010 Silicon Laboratories, Inc.
// http://www.silabs.com
//
// Program Description:
//
// [*** TEMPLATE INFORMATION ***]
// Filename: Fnnn_TargetBL_DevSpecific.c
// nnn => Fill-in with the MCU family part number.
// Examples: TargetBL_DevSpecific.c, TargetBL_DevSpecific.c
//
//
// Target:         C8051Fxxx (Any Silicon Labs Flash MCU)
// Tool chain:     Generic
// Command Line:   None
//
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include "TargetBL_Config.h"
#include "TargetBL_Interface.h"

#include "UART_Interface.h"

//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------

// ------------------------------------------
// *** Device-Specific *** 
// Change this as necessary based on MCU
// ------------------------------------------

//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
extern U8 data server_address;
U16 data timeout = FIVE_SEC;

//-----------------------------------------------------------------------------
// Function Prototypes (Local)
//-----------------------------------------------------------------------------
void OSCILLATOR_Init(void);
void PORT_Init(void);
void UART0_Init(void);
void Read_Address(void);
bit Timeouts();

//=============================================================================
// Function Definitions
//=============================================================================
void Disable_Watchdog(void)
{
    PCA0MD &= ~0x40; // Disable Watchdog
}

void Device_Init(void)
{
    Disable_Watchdog();
    OSCILLATOR_Init(); // Configure system clock
    PORT_Init(); // Initialize crossbar
    Read_Address();
    UART0_Init(); // Init UART0 & Timer1 (Data source comm)
}

//-----------------------------------------------------------------------------
// OSCILLATOR_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// This routine initializes the system clock to use the internal oscillator
// at its maximum frequency.
// Also enables the Missing Clock Detector.
//-----------------------------------------------------------------------------
void OSCILLATOR_Init(void)
{
    SFRPAGE = CONFIG_PAGE;
    OSCICN = 0xC7; // Set system clock to 24 MHz
    SFRPAGE = ACTIVE_PAGE;

    VDM0CN = 0x80; // Enable VDD monitor and early warning
    RSTSRC = 0x02; // Enable VDD monitor as a reset source
}

//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Configure the Crossbar and GPIO ports.
//
// P0.4   digital   push-pull    UART0 TX
// P0.5   digital   open-drain   UART0 RX
//
// P1.3   digital  push-pull     LED
// P0.7   digital  open-drain    SW

//-----------------------------------------------------------------------------
void PORT_Init(void)
{
    SFRPAGE = CONFIG_PAGE;
    // Initialize port I/O
    P0MDOUT = 0x10; // Enable UART0 TX as push-pull output
    XBR0 = 0x01; // Enable UART0
    XBR2 = 0x40; // Enable crossbar
    SFRPAGE = ACTIVE_PAGE;
}


//-----------------------------------------------------------------------------
// UART0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Configure the UART0 using Timer1, for <BAUDRATE> and 8-N-1.
//-----------------------------------------------------------------------------
void UART0_Init(void)
{
    SCON0 = 0x10; // SCON0: 8-bit variable bit rate
    SFRPAGE = CONFIG_PAGE;
    //        level of STOP bit is ignored
    //        RX enabled
    //        ninth bits are zeros
    //        clear RI0 and TI0 bits
    #if (SYSCLK / BAUDRATE / 2 / 65536 < 1)
    {
        SBRLH0 = -(SYSCLK / BAUDRATE / 2) >> 8;
        SBRLL0 = -(SYSCLK / BAUDRATE / 2);
        SBCON0 = 0x43;
    }
    #elif (SYSCLK / BAUDRATE / 2 / 65536 < 4)
    {
        SBRLH0 = -(SYSCLK / BAUDRATE / 2 / 4) >> 8;
        SBRLL0 = -(SYSCLK / BAUDRATE / 2 / 4);
        SBCON0 = 0x41;
    }
    #elif (SYSCLK / BAUDRATE / 2 / 65536 < 12)
    {
        SBRLH0 = -(SYSCLK / BAUDRATE / 2 / 12) >> 8;
        SBRLL0 = -(SYSCLK / BAUDRATE / 2 / 12);
        SBCON0 = 0x40;
    }
    #else
    {
        SBRLH0 = -(SYSCLK / BAUDRATE / 2 / 48) >> 8;
        SBRLL0 = -(SYSCLK / BAUDRATE / 2 / 48);
        SBCON0 = 0x42;
    }
    #endif
    SFRPAGE = ACTIVE_PAGE;

    TMOD = 0x01;
    TR0 = 1; // START Timer0
}

void Read_Address()
{
    server_address  = 0x0D;     // ((P3 & 0x04) >> 2) + 0x0D;
}

U16 SystemTick()
{
    U8 hi, lo;

    do
    {
        hi = TH0;
        lo = TL0;
    }
    while(hi != TH0);

    return hi << 8 | lo;
}

bit Timeouts()
{
    if (TF0)
    {
        TF0 = 0;
        if (timeout)
            --timeout;
    }
    return timeout == 0;
}

void ResetTimeouts()
{
    timeout = FIVE_SEC;
}

//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------
